/** @format */

// 初始化游戏数据
const data = {
    board: [
        [2, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ],
    score: { recent: 0, history: 0 }
}
function initData(){}
/**
 * @function 获取新块
 * @return {object} result => {coordinate:坐标,value:值}
 */
function getNewBlock(matrix = data.board) {
    const [M, N] = [matrix.length, matrix[0].length]
    const emptyBlocks = []
    for (let i = 0; i < M; i++) {
        for (let j = 0; j < N; j++) {
            if (matrix[i][j] == 0) emptyBlocks.push([i, j])
        }
    }
    let i = Math.floor(Math.random() * emptyBlocks.length)
    const result = { coordinate: emptyBlocks[i], value: Math.random() < 0.5 ? 2 : 4 }
    matrix[result.coordinate[0]][result.coordinate[1]] = result.value
    return result
}
// 判断索引越界
function isInRange(i, j, matrix = data.board) {
    const [M, N] = [matrix.length, matrix[0].length]
    if (i >= 0 && i < M && j >= 0 && j < N) return true
    else return false
}
/**
 * @function 合并块
 * @param {string} direction 合并方向
 * @param {number} score 得分
 */
function mergeBlocks(direction, matrix = data.board, score = data.score) {
    console.log(direction)
    const [M, N] = [matrix.length, matrix[0].length]
    // 获取下一个元素坐标
    const next = {
        Up: (i, j) => [--i, j],
        Down: (i, j) => [++i, j],
        Left: (i, j) => [i, --j],
        Right: (i, j) => [i, ++j]
    }
    function mergeAline(i, j, direction) {
        console.log(i, j, direction)
        let [nextI, nextJ] = next[direction](i, j)
        while (isInRange(nextI, nextJ)) {
            console.log("try to merge")
            if (matrix[nextI][nextJ] == 0) [nextI, nextJ] = next[direction](nextI, nextJ)
            else if (matrix[i][j] == 0) {
                matrix[i][j] = matrix[nextI][nextJ]
                matrix[nextI][nextJ] = 0
                moved = true
            } else if (matrix[i][j] == matrix[nextI][nextJ]) {
                matrix[i][j] *= 2
                score.value += matrix[i][j]
                matrix[nextI][nextJ] = 0
                ;[i, j] = next[direction](i, j)
                moved = true
            } else {
                ;[i, j] = next[direction](i, j)
                if (i == nextI && j == nextJ) [nextI, nextJ] = next[direction](nextI, nextJ)
                else {
                    ;[matrix[i][j], matrix[nextI][nextJ]] = [matrix[nextI][nextJ], matrix[i][j]]
                    moved = true
                }
            }
        }
        console.log("mergedAline:", matrix)
    }
    let [i, j, moved] = [0, 0, false]
    switch (direction) {
        case "Up":
            while (j < N) {
                mergeAline(i, j, "Down")
                // ;[i, j] = next['Right'](i, j)
                j++
            }
            break
        case "Down":
            i = M - 1
            while (j < N) {
                mergeAline(i, j, "Up")
                // ;[i, j] = next['Right'](i, j)
                j++
            }
            break
        case "Left":
            while (i < M) {
                mergeAline(i, j, "Right")
                // ;[i, j] = next['Down'](i, j)
                i++
            }
            break
        case "Right":
            j = N - 1
            while (i < M) {
                mergeAline(i, j, "Left")
                // ;[i, j] = next['Down'](i, j)
                i++
            }
            break
    }
    console.log("after merged:", matrix)
    console.log("moved is:", moved)
    if (moved) {
        getNewBlock()
        console.log("createNewBlock")
    }
    // return movements
}
function updateView() {}
